

;(function(){
        var SchemeConstants = {
            openBluetoothAdapter               : 'ble_open_adapter',
            closeBluetoothAdapter              : 'ble_close_adapter',
            getBluetoothAdapterState           : 'ble_get_adapter_state',
            onBluetoothAdapterStateChange      : 'ble_on_adapter_state_change',
            startBluetoothDevicesDiscovery     : 'ble_start_device_discovery',
            stopBluetoothDevicesDiscovery      : 'ble_stop_device_discovery',
            getBluetoothDevices                : 'ble_get_devices',
            onBluetoothDeviceFound             : 'ble_on_device_found',
            getConnectedBluetoothDevices       : 'ble_get_connected_devices',
            createBLEConnection                : 'ble_create_connection',
            closeBLEConnection                 : 'ble_close_connection',
            getBLEDeviceServices               : 'ble_get_device_services',
            getBLEDeviceCharacteristics        : 'ble_get_device_characteristics',
            readBLECharacteristicValue         : 'ble_read_characteristic_value',
            writeBLECharacteristicValue        : 'ble_write_characteristic_value',
            notifyBLECharacteristicValueChange : 'ble_notify_characteristic_value_change',
            onBLEConnectionStateChange         : 'ble_on_connection_state_change',
            onBLECharacteristicValueChange     : 'ble_on_characteristic_value_change',
        }
  
        var _identifer = (new Date()).getTime();
  
        var _callCommonFunction = function(object, string) {
            object['identifier'] = _identifer
            window.pajkDispatchScheme(function(res) {
                if (!object) {
                    return;
                }

                if (typeof(object['success']) == 'function') {
                    console.log(string,'----success')
                    object['success'](res)
                }
                if (typeof(object['complete']) == 'function') {
                    console.log(string, '----complete')
                    object['complete'](res)
                }
            }, function(res) {
                if (!object) {
                    return;
                }
                if (typeof(object['fail']) == 'function') {
                    console.log(string, '-----fail')
                    object['fail'](res)
                }
                if (typeof(object['complete']) == 'function') {
                    console.log(string, '-----complete')
                    object['complete'](res)
                }
            }, object, string);
        };


        /**
         * 十六进制字符串转ArrayBuffer
         */
        var _hex2ab = function(hex) {
            var typedArray = new Uint8Array(hex.match(/[\da-f]{2}/gi).map(function(h) {//此处正则正式引入js时需要去除一个"\"
                return parseInt(h, 16);
            }));
            
            var buffer = typedArray.buffer;
            return buffer;
        };
        
        // ArrayBuffer转16进度字符串
        var _ab2hex = function (buffer) {
            var hexArr = Array.prototype.map.call(new Uint8Array(buffer), function (bit) {
                            return ('00' + bit.toString(16)).slice(-2);
                         });
            return hexArr.join('');
        };

        var PAG_NATIVE = window.PAG_NATIVE =  {};

        /*
         * PAG_NATIVE.openBluetoothAdapter(Object object)
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.openBluetoothAdapter = function(object) {
            _callCommonFunction(object, SchemeConstants.openBluetoothAdapter);
        };
        
        /*
         * PAG_NATIVE.closeBluetoothAdapter(Object object)
         * 关闭蓝牙连接，释放资源
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.closeBluetoothAdapter = function(object) {
            _callCommonFunction(object, SchemeConstants.closeBluetoothAdapter);
        };
        
        /*
         * PAG_NATIVE.getBluetoothAdapterState(Object object)
         * 获取蓝牙适配器状态，如果蓝牙未开或不可用，这里可用检测到
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.getBluetoothAdapterState = function(object) {
            console.log("PAG_NATIVE.getBluetoothAdapterState");
            _callCommonFunction(object, SchemeConstants.getBluetoothAdapterState);
        };
        
        /*
         * PAG_NATIVE.onBluetoothAdapterStateChange(function callback)
         * 蓝牙适配器状态发生变化事件，这里可用监控蓝牙的关闭和打开动作
         * @param available   boolean 蓝牙适配器是否可用
         * @param discovering boolean 蓝牙适配器是否处于搜索状态
         */
        PAG_NATIVE.onBluetoothAdapterStateChange = function(callback) {
            console.log("PAG_NATIVE.onBluetoothAdapterStateChange");
            if ('function' !== typeof(callback)) {
                return;
            }

            var params = {identifier:_identifer, eventName:SchemeConstants.onBluetoothAdapterStateChange};
            window.pajkRegisterEvent(params.eventName, function(data){
                console.log("PAG_NATIVE.onBluetoothAdapterStateChange");
                do
                {
                    if ( 'object' !== typeof(data) ) {
                        break;
                    }
                    callback(data['data']);                    
                }
                while(0)
            });

            //将事件通知将native
            window.pajkDispatchScheme(null, null, params, SchemeConstants.onBluetoothAdapterStateChange);
        };
        
        /*
         * PAG_NATIVE.startBluetoothDevicesDiscovery(Object object)
         * 开始搜索设备，蓝牙初始化成功后就可以搜索设备
         * @param services Array<string>
         * @param allowDuplicatesKey boolean
         * @param interval number
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.startBluetoothDevicesDiscovery = function(object) {
            _callCommonFunction(object, SchemeConstants.startBluetoothDevicesDiscovery);
        };
        
        /*
         * PAG_NATIVE.stopBluetoothDevicesDiscovery(Object object)
         * 停止搜寻附近的蓝牙外围设备。若已经找到需要的蓝牙设备并不需要继续搜索时，建议调用该接口停止蓝牙搜索
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.stopBluetoothDevicesDiscovery = function(object) {
            _callCommonFunction(object, SchemeConstants.stopBluetoothDevicesDiscovery);
        };
        
        /*
         * PAG_NATIVE.getBluetoothDevices
         * 获取在小程序蓝牙模块生效期间所有已发现的蓝牙设备
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.getBluetoothDevices = function(object) {
            object['identifier'] = _identifer
            window.pajkDispatchScheme(function(res) {
                if (typeof(object['success']) == 'function') {
                    do
                    {
                        if (res['devices'] == undefined) {
                            break;
                        }
                        for (var i = 0; i < res['devices'].length; i++) {
                            if (res['devices'][i]['advertisData'] == undefined || res['devices'][i]['advertisData'].length == 0) {
                                break;
                            }
                            res['devices'][i]['advertisData'] = _hex2ab(res['devices'][i]['advertisData']);
                        }
                        object['success'](res);
                    }while(0)
                }
                if (typeof(object['complete']) == 'function') {
                    object['complete']('getBluetoothDevices--complete');
                }
            }, function(res) {
                if (typeof(object['fail']) == 'function') {
                    object['fail'](res);
                }
                if (typeof(object['complete']) == 'function') {
                    object['complete']('getBluetoothDevices--complete');
                }
            }, object, SchemeConstants.getBluetoothDevices);
        };
        
        
        /*
         * PAG_NATIVE.onBluetoothDeviceFound(function callback)
         * 当搜索到一个设备时的事件，在此可用过滤目标设备
         */
        PAG_NATIVE.onBluetoothDeviceFound = function(callback) {

            if ('function' !== typeof(callback)) {
                return;
            }

            var params = {identifier:_identifer, eventName:SchemeConstants.onBluetoothDeviceFound};
            window.pajkRegisterEvent(params.eventName, function(data) {
                do
                {
                    if ( 'object' !== typeof(data) ) {
                        break;
                    }
                    var res = data['data'];
                    if ( 'object' !== typeof(res) ) {
                        break;
                    }
                    var devices = res.devices;
                    if ('object' !== typeof(devices)) {
                        break;
                    }
                    for (var i = 0 ; i < devices.length; i++) {
                        if (devices[i]['advertisData']) {
                            devices[i]['advertisData'] = _hex2ab(devices[i]['advertisData']);
                        }
                    }

                    //需要对data数据格式转换data.res.devices
                    callback(res);

                }while(0)

            });
            window.pajkDispatchScheme(null, null, params, SchemeConstants.onBluetoothDeviceFound);
        };
        
        /*
         * PAG_NATIVE.getConnectedBluetoothDevices(Object object)
         * 获取已连接的设备
         * @param services Array<string>
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.getConnectedBluetoothDevices = function(object) {
            console.log('getConnectedBluetoothDevices', '实际的结果');
            _callCommonFunction(object, SchemeConstants.getConnectedBluetoothDevices);
        };
        
        /*
         * PAG_NATIVE.createBLEConnection(object)
         * 创建BLE连接
         * @param deviceId string
         * @param timeout  number
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.createBLEConnection = function(object) {
            _callCommonFunction(object, SchemeConstants.createBLEConnection);
        };
        
        /*
         * PAG_NATIVE.closeBLEConnection(object)
         * 关闭BLE连接
         * @param deviceId string (必填)
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.closeBLEConnection = function(object) {
            _callCommonFunction(object, SchemeConstants.closeBLEConnection);
        };
        
        /*
         * PAG_NATIVE.getBLEDeviceServices(object)
         * 获取设备的服务列表，每个蓝牙设备都有一些服务
         * @param deviceId string (必填)
         * @param success  function
         * @param fail     function
         * @param complete function
         */
        PAG_NATIVE.getBLEDeviceServices = function(object) {
            _callCommonFunction(object, SchemeConstants.getBLEDeviceServices);
        };
        
        /*
         * PAG_NATIVE.getBLEDeviceCharacteristics(object)
         * 获取蓝牙设备某个服务的特征值列表
         * @param deviceId  string (必填)
         * @param serviceId string (必填)
         * @param success   function
         * @param fail      function
         * @param complete  function
         */
        PAG_NATIVE.getBLEDeviceCharacteristics = function(object) {
            _callCommonFunction(object, SchemeConstants.getBLEDeviceCharacteristics);
        };
        
        /*
         * PAG_NATIVE.readBLECharacteristicValue(object)
         * 读取低功耗蓝牙设备的特征值的二进制数据值
         * @param deviceId         string (必填)
         * @param serviceId        string (必填)
         * @param characteristicId string (必填)
         * @param success          function
         * @param fail             function
         * @param complete         function
         */
        PAG_NATIVE.readBLECharacteristicValue = function(object) {
            _callCommonFunction(object, SchemeConstants.readBLECharacteristicValue);
        };
        
        /*
         * PAG_NATIVE.writeBLECharacteristicValue(object)
         * 向蓝牙设备写入数据
         * @param deviceId         string (必填)
         * @param serviceId        string (必填)
         * @param characteristicId string (必填)
         * @param value            ArrayBuffer (必填)
         * @param success          function
         * @param fail             function
         * @param complete         function
         */
        PAG_NATIVE.writeBLECharacteristicValue = function(object) {
            console.log('PAG_NATIVE.writeBLECharacteristicValue');
            var params = {};
            for (var key in object) {
                if (object.hasOwnProperty(key))
                {
                    var element = object[key];
                    if (element instanceof ArrayBuffer)
                    {
                        params[key] = _ab2hex(element);
                    }
                    else
                    {
                        params[key] = element;
                    }
                    
                }
            }
            _callCommonFunction(params, SchemeConstants.writeBLECharacteristicValue);
        };
        
        /*
         * PAG_NATIVE.notifyBLECharacteristicValueChange(object)
         * 开启蓝牙设备notify提醒功能，只有开启这个功能才能接受到蓝牙推送的数据
         * @param deviceId         string (必填)
         * @param serviceId        string (必填)
         * @param characteristicId string (必填)
         * @param state            boolean (必填)
         * @param success          function
         * @param fail             function
         * @param complete         function
         */
        PAG_NATIVE.notifyBLECharacteristicValueChange = function(object) {
            console.log('PAG_NATIVE.notifyBLECharacteristicValueChange');
            _callCommonFunction(object, SchemeConstants.notifyBLECharacteristicValueChange);
        };
        
        /*
         * PAG_NATIVE.onBLEConnectionStateChange(function callback)
         * 监听蓝牙设备错误事件，包括异常断开等等
         */
        PAG_NATIVE.onBLEConnectionStateChange = function(callback) {
            console.log('PAG_NATIVE.onBLEConnectionStateChange');
            if ('function' !== typeof(callback)) {
                return;
            }

            var params = {identifier:_identifer, eventName:SchemeConstants.onBLEConnectionStateChange};

            window.pajkRegisterEvent(params.eventName, callback);
            window.pajkDispatchScheme(null, null, params, SchemeConstants.onBLEConnectionStateChange);
        };
        
        /*
         * PAG_NATIVE.onBLECharacteristicValueChange(function callback)
         * 监听蓝牙推送的数据，也就是notify数据
         * @param deviceId         string
         * @param serviceId        string
         * @param characteristicId string
         * @param value            ArrayBuffer
         */
        PAG_NATIVE.onBLECharacteristicValueChange = function(callback) {

            if ('function' !== typeof(callback)) {
                return;
            }

            var params = {identifier:_identifer, eventName:SchemeConstants.onBLECharacteristicValueChange};

            window.pajkRegisterEvent(params.eventName, function(data) {
                do
                {
                    if ( 'object' !== typeof(data) ) {
                        break;
                    }
                    var characteristic = data['data'];
                    if ( 'object' !== typeof(characteristic) ) {
                        break;
                    }
                    if ( 'string' !== typeof(characteristic.value) ) {
                        break;
                    }

                    if ( characteristic.value ) {
                        characteristic.value = _hex2ab(characteristic.value);
                    }
                    callback(characteristic);

                }while(0);
            });
            window.pajkDispatchScheme(null, null, params, SchemeConstants.onBLECharacteristicValueChange);
        };        
    })();

